<script setup lang="ts">
import YkEmptyBox from '@yk/components/empty-box/YkEmptyBox.vue'
import { PreferenceDB } from '@utils/indexedDB/preference'
import { Plus, Search } from '@element-plus/icons-vue'
import { ElTree } from 'element-plus'
import { EmptyEnum, EmptyState } from '@yk/components/empty-box/type'
import { getDeviceBySceneTreeAPI, getDeviceDetailByIdAPI } from '@/api/device'
import { AxiosAPIResultType } from '@utils/request/type'
import { ArrayType } from '@/typings'
import { DeviceDTO } from '@/api/entity/device'
import { ObjectUtil } from '@utils/object-util'
import { TabBarUtil } from '@/layout/components/tab-bar'
import { useDeviceStatusStore } from '@/dataset/device-status/store'
import { FileUtil, MountedCheck, toEditPageCheck } from '@/utils'
import { DeviceRoleUtil } from '@/dataset/device-role'
import { getEncryptVStr } from '@/router/interceptor/security'
import { getSelfBySceneIdAPI } from '@/api/self-config'
import { unShareDeviceAPI } from '@/api/share'

const route = useRoute()
const router = useRouter()
defineOptions({ name: 'DeviceData' })

const routerQuery = shallowRef({
  id: ''
})
const mc = new MountedCheck()
onMounted(() => {
  routerQuery.value = route.query as any
  DeviceRoleUtil.updateRole()
  init()
  mc.end()
})

watch(() => route.name, () => {
  // 解决点击菜单导致地址重置（因为页面添加了Keep，所以不再进入onMounted）
  if (route.name === 'DeviceData' && tagsActiveName.value) {
    router.push({ name: tagsActiveName.value })
  } else if (tagsActiveList.value[route.name]) {
    tagsActiveName.value = route.name as string
  }
})

onActivated(() => {
  if (mc.isMounted()) return
  routerQuery.value = route.query as any
  // 如果已打开的情况下其他页面需要切换页面
  if (routerQuery.value.id) {
    setCurrentDeviceById(routerQuery.value.id)
  }
  DeviceRoleUtil.updateRole()
  deviceStatusStore.startUpdateStatus()
})

onDeactivated(() => {
  deviceStatusStore.stopUpdateStatus()
})

onBeforeUnmount(() => {
  deviceStatusStore.stopUpdateStatus()
})

function init () {
  // 获取设列表
  getDeviceTreeList()
  initActiveName()
  deviceStatusStore.startUpdateStatus()
}

// region TODO 在线状态
const deviceStatusStore = useDeviceStatusStore()
// endregion

// region TODO 设备树
type DeviceTreeNodeType = ArrayType<AxiosAPIResultType<typeof getDeviceBySceneTreeAPI>['data']>
const deviceTreeList = ref<DeviceTreeNodeType[]>([])
const deviceTreeRef = shallowRef<InstanceType<typeof ElTree>>()
const currentDevice = shallowRef<DeviceDTO>(null)
const defaultExpandedKeys = ref([])
// 获取设备列表
function getDeviceTreeList () {
  const loading = ElLoading.service()
  getDeviceBySceneTreeAPI().then((res) => {
    res.result().then((rdata) => {
      deviceTreeList.value = rdata.data
      // 如果树搜索有搜索条件，执行一次搜索
      if (treeFilterText.value) {
        nextTick(() => {
          deviceTreeRef.value.filter(treeFilterText.value)
        })
      }
      // 如果地址中有id，默认优选选中
      if (routerQuery.value.id) {
        nextTick(() => {
          setCurrentDeviceById(routerQuery.value.id)
        })
      } else {
        // 根据最后一次操作的设备选中设备
        PreferenceDB.DeviceData.getItem('currentDevice').then((e) => {
          if (e) {
            setCurrentDeviceById(e)
          }
        })
      }
    })
  }).finally(loading.close)
}
// 树节点点击实现
function deviceTreeNodeClickHandle (data: DeviceTreeNodeType) {
  if (data.isDevice) {
    setCurrentDevice(data.data)
  }
}
// 设置当前选中设备
function setCurrentDevice (data: DeviceDTO) {
  if (data.id !== currentDevice.value?.id) {
    getDeviceDetailByIdAPI({ id: data.id }).then((res) => {
      res.result().then((rdata) => {
        currentDevice.value = rdata.data
        PreferenceDB.DeviceData.setItem('currentDevice', data.id)
      })
    })
  }
}
function setCurrentDeviceById (id: string) {
  const key = 'D' + id
  const node = deviceTreeRef.value.getNode(key)
  // 如果树中还有这个设备
  if (node) {
    // 选中这个设备
    setCurrentDevice(node.data.data)
    // 展开这个设备所在的层级
    defaultExpandedKeys.value = [key, 'S0']
    deviceDataState.value = EmptyEnum.SUCCESS
  }
}

// region TODO 树搜索
const treeFilterText = ref('')
watch(treeFilterText, (val) => {
  deviceTreeRef.value.filter(val)
})
const filterNode = (value: string, data: DeviceTreeNodeType) => {
  if (!value) return true
  return data.label.includes(value)
}
// endregion
// endregion

// region TODO 选项卡（菜单）
const tagsActiveName = ref('')
const tagsActiveList = shallowRef({
  DeviceRealtime: '实时数据',
  DeviceHistoryData: '历史数据',
  DeviceAlarmRecord: '报警记录',
  DeviceLog: '设备日志'
})
// 初始化选项卡
function initActiveName () {
  // 选择菜单
  if (route.name === 'DeviceData') {
    PreferenceDB.DeviceData.getItem('tagsActiveName').then((e) => {
      setTagsActiveName(e || 'DeviceRealtime')
    })
  } else if ((route.name as string) !== tagsActiveName.value && !!tagsActiveList.value[route.name]) {
    setTagsActiveName(route.name as string)
  }
}
// 设置选中选项卡
function setTagsActiveName (name: string) {
  tagsActiveName.value = name
  tagsActiveNameChangeHandel()
}
// 选项卡切换事件
function tagsActiveNameChangeHandel () {
  PreferenceDB.DeviceData.setItem('tagsActiveName', tagsActiveName.value)
  router.push({ name: tagsActiveName.value })
}
// endregion

// region TODO 页面无变量提醒
const deviceDataState = shallowRef<EmptyState>(EmptyEnum.NONE)
watch(currentDevice, () => {
  if (currentDevice.value) {
    deviceDataState.value = EmptyEnum.SUCCESS
  } else {
    deviceDataState.value = { type: EmptyEnum.EMPTY_VAR, description: '暂无数据，请选择设备' }
  }
}, { immediate: true })

// endregion

// region TODO 跳转
// 设备分享
function toDeviceShare () {
  if (!DeviceRoleUtil.isManager(currentDevice.value.id)) return
  const _route = TabBarUtil.value.getTagInfo('DeviceShare')
  if (_route && _route.query.id !== currentDevice.value.id) {
    TabBarUtil.value.close('DeviceShare')
  }
  router.push({ name: 'DeviceShare', query: { id: currentDevice.value.id } })
}
// 网关
function toGateway () {
  TabBarUtil.value.reopen({ name: 'GatewayManage', params: { id: currentDevice.value.gatewayId } })
}
// 变量模板
function toVariableTemplate () {
  const _route = TabBarUtil.value.getTagInfo('EditVariableTemplate')
  if (_route && _route.query.id !== currentDevice.value.templateId) {
    TabBarUtil.value.close('EditVariableTemplate')
  }
  router.push({ name: 'EditVariableTemplate', query: { id: currentDevice.value.templateId } })
}
// 设备配置
function toEditDevice () {
  toEditPageCheck({
    id: currentDevice.value.id,
    name: 'EditDevice',
    message: '已存在未编辑完成的表单',
    query: { id: currentDevice.value.id }
  })
}
// 报警配置
function toAlarmRule () {
  TabBarUtil.value.reopen({ name: 'AlarmRule', params: { deviceId: currentDevice.value.id } })
}
// 组态
function toSelf (id: string) {
  getSelfBySceneIdAPI({ id }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || []
      const self = data[0]
      if (self?.id) {
        window.open('/#/show-draw?v=' + getEncryptVStr({ query: { id: self.id } }), '_blank')
      } else {
        ElMessageBox.alert('该场景未配置组态，是否前往组态页面添加？', '提醒', {
          confirmButtonText: '前往'
        }).then(() => {
          router.push({ name: 'SelfConfigManage' })
        })
      }
    })
  })
}
// 视频
function toVideo () {
  router.push({ name: 'VideoIndex' })
}
// endregion

// region TODO 树 - 隐藏&显示
const isShowTreeBox = shallowRef(true)
function toggleShowTreeBox () {
  isShowTreeBox.value = !isShowTreeBox.value
}
// endregion

// region TODO 解绑设备
function unbindDevice () {
  ElMessageBox.confirm('解绑设备后无法继续查看设备数据，是否继续？', '解绑提醒').then(res => {
    const loading = ElLoading.service()
    unShareDeviceAPI({ id: currentDevice.value.id }).then((res) => {
      res.result().then(() => {
        ElMessage.success('设备已解绑')
        PreferenceDB.DeviceData.setItem('currentDevice', undefined)
        currentDevice.value = null
        init()
      })
    }).finally(loading.close)
  })
}
// endregion
</script>

<template>
  <div class="layout_view d-flex h-100" style="min-height: 900px">
    <!--设备列表-->
    <div class="d-flex position-relative h-100" style="flex-shrink: 0;">
      <div :style="{ width: isShowTreeBox ? '332px' : 0 }" class="h-100 overflow-hidden" style="transition: all .3s ease-in-out;">
        <div class="h-100 pr-12">
          <div class="c_card-white h-100" style="width: 320px;">
            <div class="c_card_header bor-divider-b">
              <div class="c_card-title">设备列表</div>
              <div class="c_header_right">
                <el-link type="primary" href="/#/device/add-device">
                  <el-icon><Plus /></el-icon>
                  <span>添加设备</span>
                </el-link>
              </div>
            </div>
            <div class="pt-16" style="height: var(--card-body-height);">
              <div class="d-flex-between-center">
                <el-input v-model="treeFilterText" class="c_input-search" placeholder="输入名称搜索" :prefix-icon="Search as any" />
                <refresh-btn class="fs-24 color-primary ml-2" @click="init" />
              </div>
              <div class="overflow-auto mt-16 device-tree" style="height: calc(100% - 50px);">
                <el-tree
                  ref="deviceTreeRef" :data="deviceTreeList" node-key="key"
                  highlight-current :default-expanded-keys="defaultExpandedKeys"
                  :filter-node-method="filterNode as any"
                  @node-click="deviceTreeNodeClickHandle"
                >
                  <template #default="{ node, data }">
                    <!--设备-->
                    <div v-if="data.isDevice" class="fs-14 d-flex-center device-tree__device" :class="{ 'is-active': currentDevice?.id === data.value }">
                      <div class="mr-8 d-flex-center" :class="{ 'color-success': deviceStatusStore.devicesStatus[data.value] }">
                        <ic-device-device1 />
                      </div>
                      <span>{{ node.label }}</span>
                    </div>
                    <!--场景-->
                    <div v-else class="fs-14 d-flex-between-center w-100 device-tree__scene">
                      <div class="d-flex align-items-center">
                        <ic-data-layers class="mr-8" />
                        <span>{{ node.label }}</span>
                      </div>
                      <div v-if="data.value" class="operation">
                        <el-link type="primary" @click.stop @click="toSelf(data.value)">组态</el-link>
                        <el-link type="primary" class="ml-12" @click.stop="toVideo">视频</el-link>
                      </div>
                    </div>
                  </template>
                </el-tree>
              </div>
            </div>
          </div>
        </div>
      </div>
      <collapse-side
        :collapse="!isShowTreeBox" mirroring
        class="position-absolute"
        :style="{ right: isShowTreeBox ? '-7px' : '-19px' }"
        style="top: 50%;z-index: 101;"
        @click="toggleShowTreeBox"
      />
    </div>
    <!--右侧内容-->
    <div class="flex-1 w-0" :class="{ 'c_card-page': !currentDevice }">
      <yk-empty-box :state="deviceDataState" class="h-100" :image-size="192">
        <div v-if="currentDevice" class="d-flex flex-column h-100">
          <!--基本信息-->
          <div class="c_card-white device-info position-relative">
            <!--设备名称-->
            <div class="d-flex align-items-center">
              <el-tag v-if="deviceStatusStore.devicesStatus[currentDevice.id]" type="success" effect="dark" size="small">在线</el-tag>
              <el-tag v-else type="info" effect="dark" size="small">离线</el-tag>
              <span class="ml-8">{{ currentDevice.deviceName }}</span>
            </div>
            <!--设备信息-->
            <div class="d-flex mt-12">
              <!--图片-->
              <el-image
                :src="FileUtil.prefixImage(currentDevice.url, FileUtil.DefaultImage.Device)"
                style="width: 140px;aspect-ratio: 1;" fit="contain"
              />
              <div class="d-flex justify-content-between flex-1">
                <!--基本信息-->
                <div class="ml-16 flex-1 d-flex">
                  <el-descriptions :column="2" style="min-width: 500px;max-width: 1000px;" class="">
                    <el-descriptions-item label="关联网关：" style="width: 600px;">
                      <el-link v-if="DeviceRoleUtil.isAdmin(currentDevice.id)" type="primary" @click="toGateway">{{ currentDevice.gatewayName }}</el-link>
                      <span v-else>{{ currentDevice.gatewayName }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item label="设备所有人：">{{ ObjectUtil.isEmptyToVal(currentDevice.adminName, '/') }}</el-descriptions-item>
                    <el-descriptions-item label="关联变量模板：">
                      <el-link v-if="DeviceRoleUtil.isManager(currentDevice.id)" type="primary" @click="toVariableTemplate">{{ currentDevice.templateName }}</el-link>
                      <span v-else>{{ currentDevice.templateName }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item label="设备分享：">
                      <el-link v-if="DeviceRoleUtil.isManager(currentDevice.id)" type="primary" @click="toDeviceShare">{{ currentDevice.shareNum }}人</el-link>
                      <span v-else>{{ currentDevice.shareNum }}人</span>
                    </el-descriptions-item>
                    <el-descriptions-item label="物联网卡号：" :span="2">
                      <!--<el-link type="primary">{{ ObjectUtil.isEmptyToVal(currentDevice.cardNumber, '/') }}</el-link>-->
                      <span>{{ ObjectUtil.isEmptyToVal(currentDevice.cardNumber, '/') }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item label="设备地址：">{{ currentDevice.address }}</el-descriptions-item>
                  </el-descriptions>
                  <el-descriptions :column="1">
                    <el-descriptions-item label="备注：">{{ currentDevice.notes || '/' }}</el-descriptions-item>
                  </el-descriptions>
                </div>
                <!--操作按钮-->
                <div class="">
                  <!--分享设备 & 解绑设备-->
                  <div class="d-flex" style="right: 20px;top: 20px;">
                    <!--分享设备-->
                    <div v-if="!DeviceRoleUtil.isAdmin(currentDevice.id)" class="operation-box" @click="unbindDevice">
                      <div class="icon">
                        <ic-system-unshare />
                      </div>
                      <span>解绑设备</span>
                    </div>
                    <!--分享设备-->
                    <div v-if="DeviceRoleUtil.isManager(currentDevice.id)" class="operation-box" @click="toDeviceShare">
                      <div class="icon">
                        <ic-system-share />
                      </div>
                      <span>分享设备</span>
                    </div>
                  </div>

                  <!--设备配置&报警配置-->
                  <div class="d-flex" style="right: 20px;bottom: 20px;">
                    <!--设备配置-->
                    <div class="operation-box" @click="toEditDevice()">
                      <div class="icon">
                        <ic-system-bookmark />
                      </div>
                      <span>设备配置</span>
                    </div>
                    <!--报警配置-->
                    <div v-if="DeviceRoleUtil.isManager(currentDevice.id)" class="operation-box" @click="toAlarmRule()">
                      <div class="icon">
                        <ic-system-bookmark />
                      </div>
                      <span>报警配置</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <!--选项卡-->
          <div class="c_card-white mt-12 py-0" style="height: 40px;">
            <el-tabs v-model="tagsActiveName" class="c_tabs-default" style="margin-bottom: -15px;" @tab-change="tagsActiveNameChangeHandel">
              <el-tab-pane v-for="(item,key) in tagsActiveList" :key="key" :label="item" :name="key" />
            </el-tabs>
          </div>
          <!--子页面-->
          <div class="flex-1 mt-12 overflow-hidden">
            <router-view v-slot="{ Component }">
              <keep-alive :include="['DeviceRealtime', 'DeviceHistoryData', 'DeviceAlarmRecord']">
                <component :is="Component" :device="currentDevice" />
              </keep-alive>
            </router-view>
          </div>
        </div>
      </yk-empty-box>
    </div>
  </div>
</template>

<style scoped lang="scss">
// 设备树
.device-tree {
  .device-tree__device {
    &.is-active {
      color: var(--el-color-primary);
    }
  }
  .device-tree__scene {
    height: 100%;
    .operation {
      transition: opacity 0.3s linear;
      opacity: 0;
      padding-right: 8px;
    }
    &:hover {
      .operation {
        opacity: 1;
      }
    }
  }
}

// 设备信息
.device-info {
  .operation-box {
    width: 64px;
    height: 64px;
    @include d-flex(center);
    flex-direction: column;
    font-size: 12px;
    cursor: pointer;
    color: var(--el-text-color-primary);
    .icon {
      width: 32px;
      aspect-ratio: 1;
      border-radius: 6px;
      background-color: #F7F8FA;
      font-size: 18px;
      @include d-flex(center);
      margin-bottom: 4px;
      color: var(--el-color-primary);
    }
  }
}

</style>
